#!/usr/bin/env python3
# coding: utf-8

# Copyright (c) 2020-2024 Huawei Technologies Co., Ltd.
# oec-hardware is licensed under the Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#     http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
# PURPOSE.
# See the Mulan PSL v2 for more details.
# Create: 2025-02-10
# Desc: invoke the api that traverses the test platform.

import requests
import json
import time
from datetime import datetime, timedelta
import traversal_parameters


def send_test_request(create_parameters):
    """
    新建测试请求
    后端返回任务ID
    """
    api_url = traversal_parameters.create_test_url
    try:
        response = requests.post(api_url, json=create_parameters)
        response.raise_for_status()  # 检查HTTP错误
        response_json = response.json()
        print(response_json)
        if response_json['result'] == 'fail':
            print(f"操作失败: {response_json['msg']}")
        else:
            demand_id = response_json['data']
            if demand_id is not None:
                data_length = len(demand_id)
                print(f"数据长度：{data_length}")
                return demand_id
            else:
                print("警告：即使操作结果不是 'fail'，'data' 字段仍然是 None。")
    except requests.exceptions.RequestException as e:
        print(f"请求失败: {e}")
        return None


def get_test_result(demand_id):
    """
    轮询/等待测试结果
    接口逻辑：每60秒调用一次后端接口进行任务查询
        任务执行大体分为5个阶段，预设每个阶段最长执行时间为2天，2天仍未完成当前阶段任务，停止轮询
        任务执行的所有阶段完成后，保存新一次log，由后续向对log内容进行解析
    """
    result_url = traversal_parameters.get_test_result_url + {demand_id}
    previous_status_values = None
    last_status_change_time = datetime.now()
    polling_interval_seconds = 60  # polling_interval_seconds(int): 轮询间隔时间，单位秒，默认为60秒

    print(f"开始轮询监控 API: {result_url}")

    while True:
        try:
            response = requests.get(result_url)
            response.raise_for_status()  # 检查请求是否成功 (HTTP 状态码 200)
            response_json = response.json()

            current_status_values = {}
            status_changed = False # 状态变动标记
            task_final_status_reached = False # 是否为最终状态标记
            status_fields_to_monitor = {
                "status"
            }
            stability_time_days = 2 # 最大超时时间
            output_file_path = "api_response.json" # 测试log保存位置
            task_status_field = "status"
            finish_pending_status_values = {
                "pending",
                "finish",
                "stop"
            }

            for field in status_fields_to_monitor: # status_fields_to_monitor 需要监控的状态字段名列表
                if field in response_json:
                    current_status_values[field] = response_json[field]
                else:
                    print(f"警告: 监控的状态字段 '{field}' 未在 API 响应中找到。")
                    current_status_values[field] = None  # 字段不存在时设置为 None

            # 检查任务状态是否达到 finish_pending_status_values 中的任何一个值
            if task_status_field in response_json and response_json[task_status_field] in finish_pending_status_values:
                task_final_status_reached = True
                print(f"任务状态变为最终状态: {response_json[task_status_field]}，停止轮询。")

            if previous_status_values is None:  # 首次轮询
                previous_status_values = current_status_values
                last_status_change_time = datetime.now()
                status_changed = True  # 首次轮询也视为状态变化
            else:
                if current_status_values != previous_status_values:
                    status_changed = True
                    last_status_change_time = datetime.now()
                    previous_status_values = current_status_values
                    print(
                        f"状态字段发生变化: {current_status_values}，上次变化时间: {last_status_change_time.strftime('%Y-%m-%d %H:%M:%S')}")

            if task_final_status_reached or (not status_changed and datetime.now() - last_status_change_time >= timedelta(days=stability_time_days)):
                print("满足轮询停止条件，进行最后一次 API 调用并保存完整响应...")
                final_response = requests.get(result_url)
                final_response.raise_for_status()
                final_response_json = final_response.json()

                with open(output_file_path, 'w', encoding='utf-8') as f:
                    json.dump(final_response_json, f, ensure_ascii=False, indent=4)
                print(f"完整响应已保存到: {output_file_path}")
                break  # 退出轮询循环
            elif not task_final_status_reached and not status_changed:  # 只有当最终状态未达到 且 状态字段无变化时 才打印持续轮询信息
                time_since_last_change = datetime.now() - last_status_change_time
                print(f"状态字段无变化，已持续: {time_since_last_change.days} 天 {time_since_last_change.seconds // 3600} 小时，任务状态仍未达到最终状态，继续轮询...")
            elif not task_final_status_reached and status_changed:  # 只有当最终状态未达到 且 状态字段发生变化时 才打印继续轮询信息
                print(f"状态字段发生变化，任务状态仍未达到最终状态，继续轮询...")

            time.sleep(polling_interval_seconds)  # 等待一段时间后进行下一次轮询

        except requests.exceptions.RequestException as e:
            print(f"API 请求发生错误: {e}")
            print("等待后重试...")
            time.sleep(polling_interval_seconds)  # 发生错误也等待一段时间再重试
        except json.JSONDecodeError:
            print("API 响应内容不是有效的 JSON 格式，请检查接口返回。")
            print("等待后重试...")
            time.sleep(polling_interval_seconds)
        except Exception as e:  # 捕获其他未知异常，例如文件写入错误等
            print(f"发生未知错误: {e}")
            break  # 发生未知错误，直接退出循环 (可以根据需要修改处理方式)

def create_test_report(data):
    """
    自动化生成测试报告
    等待平台实现接口
    """
    # to_do